﻿using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Threading;

namespace Ellanet
{
    public partial class LauncherService : ServiceBase
    {
        private const string LpDesktop = @"WinSta0\Winlogon";
        private const string LogonAppsXmlPath = "LogonApps.xml";

        private readonly bool _loggingEnabled;
        private readonly string _logPath;
        private readonly int _sleepAfterLogOff;

        public LauncherService()
        {
            InitializeComponent();
            Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var xml = new LogonAppsXmlMgmt(LogonAppsXmlPath);
            xml.GetLoggingConfig(out _loggingEnabled, out _logPath, out _sleepAfterLogOff);
            ManagedSENS.SensLogon.DisplayLock += SensLogon_DisplayLock;
            ManagedSENS.SensLogon.DisplayUnlock += SensLogon_DisplayUnlock;
            ManagedSENS.SensLogon.Logon += SensLogon_Logon;
            ManagedSENS.SensLogon.Logoff += SensLogon_Logoff;
        }

        private void SensLogon_Logoff(string userName)
        {
            WriteToLog(String.Format("SensLogon_Logoff({0})", userName));
            var processEventThread = new Thread(ProcessSensEvent);
            processEventThread.Start(LogonAppsXmlMgmt.Event.LogOff);
        }

        private void SensLogon_Logon(string userName)
        {
            WriteToLog(String.Format("SensLogon_Logon({0})", userName));
            var processEventThread = new Thread(ProcessSensEvent);
            processEventThread.Start(LogonAppsXmlMgmt.Event.LogOn);
        }

        private void SensLogon_DisplayUnlock(string userName)
        {
            WriteToLog(String.Format("SensLogon_DisplayUnlock({0})", userName));
            var processEventThread = new Thread(ProcessSensEvent);
            processEventThread.Start(LogonAppsXmlMgmt.Event.DisplayUnlock);
        }

        private void SensLogon_DisplayLock(string userName)
        {
            WriteToLog(String.Format("SensLogon_DisplayLock({0})", userName));
            var processEventThread = new Thread(ProcessSensEvent);
            processEventThread.Start(LogonAppsXmlMgmt.Event.DisplayLock);
        }

        protected override void OnStart(string[] args)
        {
            WriteToLog(String.Format("OnStart()"));
            var processEventThread = new Thread(ProcessSensEvent);
            processEventThread.Start(LogonAppsXmlMgmt.Event.ServiceStart);
        }

        protected override void OnStop()
        {
            WriteToLog(String.Format("OnStop()"));
            var processEventThread = new Thread(ProcessSensEvent);
            processEventThread.Start(LogonAppsXmlMgmt.Event.ServiceStop);
        }

        private void WriteToLog(string entry)
        {
            try
            {
                if (_loggingEnabled)
                {
                    var sw = new StreamWriter(_logPath, true);
                    sw.WriteLine("{0}\t{1}", DateTime.Now, entry);
                    sw.Close();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private void ProcessSensEvent(object e)
        {
            switch ((LogonAppsXmlMgmt.Event) e)
            {
                case LogonAppsXmlMgmt.Event.LogOff:
                    Thread.Sleep(_sleepAfterLogOff);
                    break;
            }

            var xml = new LogonAppsXmlMgmt(LogonAppsXmlPath);
            var ip = new InjectProcess();

            foreach (string application in xml.GetApplications(LogonAppsXmlMgmt.Action.Stop, (LogonAppsXmlMgmt.Event) e))
            {
                WriteToLog(String.Format("Stopping\t{0}", application));
                ip.TerminateSystemProcess(application);
            }

            foreach (string application in xml.GetApplications(LogonAppsXmlMgmt.Action.Start, (LogonAppsXmlMgmt.Event) e))
            {
                WriteToLog(String.Format("Starting\t{0}", application));
                ip.Inject(LpDesktop, application);
            }
        }
    }
}
